package cn.nohan.funplay.module.member.mongo.service;

import cn.nohan.funplay.module.member.mongo.entity.MongoUserTrajectoryEntity;
import cn.nohan.funplay.module.member.mongo.mapper.LocationRepository;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.geo.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author caozhipeng
 * @date 2025/8/1
 */
@Service
public class LocationService {

    @Autowired
    private LocationRepository locationRepository;


    @Autowired
    private MongoTemplate mongoTemplate;

    private Distance fiveKilometers = new Distance(1000, Metrics.MILES);
    private Point centerPoint = new Point(120.89415521913256,31.971742189424283); // longitude, latitude


    public void init(){
//        locationRepository.deleteAll();

        // 插入一些示例数据
        // 故宫 (116.403963, 39.915119)
        locationRepository.save(new MongoUserTrajectoryEntity(1L,"南通金石国际大酒店", 31.97377910313142, 120.89270161857188));
        // 天安门广场 (116.3912757, 39.9037078)
        locationRepository.save(new MongoUserTrajectoryEntity(2L, "金石国际大酒店停车场",31.974212384500625, 120.89736240605883 ));
        // 颐和园 (116.275136, 39.999077)
        locationRepository.save(new MongoUserTrajectoryEntity(3L,"维客多酒吧", 31.97150434238698, 120.89790510049225));
        locationRepository.save(new MongoUserTrajectoryEntity(4L,"猫咪咖啡馆",31.97274386520319, 120.90050169496457 ));
        locationRepository.save(new MongoUserTrajectoryEntity(5L,"南通大学植物园", 31.970286043710725, 120.9048998469164));
        locationRepository.save(new MongoUserTrajectoryEntity(6L,"后街时光音乐酒吧",31.983331501571193, 120.90948633909638 ));
        locationRepository.save(new MongoUserTrajectoryEntity(7L,"紫琅公园", 31.962827363984132, 120.93196967090049));
        locationRepository.save(new MongoUserTrajectoryEntity(8L,"南通国际数据中心产业园",31.938137817505233, 120.9398905540166 ));
        locationRepository.save(new MongoUserTrajectoryEntity(9L,"五山森林公园", 31.934242459225, 120.89830172194134));
        locationRepository.save(new MongoUserTrajectoryEntity(10L,"濠河风景名胜区", 32.02418385493383, 120.85726955780474));
        locationRepository.save(new MongoUserTrajectoryEntity(11L,"滨江公园（东南门）", 31.9574728850114, 120.87570242412866));
        locationRepository.save(new MongoUserTrajectoryEntity(12L,"南通市环保公园", 31.98675689069807, 120.94044024208364));
        locationRepository.save(new MongoUserTrajectoryEntity(13L,"啬园", 31.966714996777117, 120.90842950023091));
        locationRepository.save(new MongoUserTrajectoryEntity(14L,"南通ＣＢＤ",31.97016457020001, 120.89181417820942 ));
        locationRepository.save(new MongoUserTrajectoryEntity(15L,"洋河蓝色经典体育场", 31.967250543722194, 120.89566486240888));
        locationRepository.save(new MongoUserTrajectoryEntity(16L,"我",31.971742189424283, 120.89415521913256 ));

    }

    public List<MongoUserTrajectoryEntity> performGeoQueries1() {
        List<MongoUserTrajectoryEntity> nearWangfujing = locationRepository.findByLocationNear(centerPoint, fiveKilometers);
        return nearWangfujing;
    }

    public Page<MongoUserTrajectoryEntity> performGeoQueries2(Integer pageNum, Integer pageSize,double maxDistance) {
        Pageable pageable = PageRequest.of(pageNum, pageSize,Sort.by(Sort.Direction.ASC,"location"));
        Distance distance = new Distance(maxDistance,Metrics.KILOMETERS);
        // 1. 查找附近 1 公里内的地点
        Page<MongoUserTrajectoryEntity> nearWangfujing = locationRepository.findByLocationNear(centerPoint, distance,pageable);
        return nearWangfujing;
    }

    public List<MongoUserTrajectoryEntity> performGeoQueries3(double maxDistance) {
        Distance distance = new Distance(maxDistance,Metrics.KILOMETERS);
        List<MongoUserTrajectoryEntity> nearWangfujing = locationRepository.findByLocationNear(centerPoint, distance);
        return nearWangfujing;
    }


    public Page<MongoUserTrajectoryEntity> performGeoQueries4(Integer pageNum, Integer pageSize,double maxDistance) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        Distance distance = new Distance(maxDistance,Metrics.KILOMETERS);
        Long userId=45L;
        // 1. 查找附近 1 公里内的地点
        Page<MongoUserTrajectoryEntity> nearWangfujing = locationRepository.findByLocationNearAndUserIdNot(centerPoint, distance,userId,pageable);
        nearWangfujing.forEach(location -> {
            // 计算距离
            Distance calculatedDistance = calculateDistance(location.getLocation(), centerPoint);
//            location.setDistance(calculatedDistance);
            location.setLocation(null);
            location.setRange(calculatedDistance);
        });
        return nearWangfujing;
    }

    public static Distance calculateDistance(Point point1, Point point2) {
        // 使用Spring Data的Distance计算
        double dx = point1.getX() - point2.getX();
        double dy = point1.getY() - point2.getY();
        double distanceInDegrees = Math.sqrt(dx * dx + dy * dy);

        // 近似转换（1度≈111公里）
        return new Distance(distanceInDegrees * 111, Metrics.KILOMETERS);
    }


    public Page<MongoUserTrajectoryEntity> findNearbyLocations(int pageNum,int pageSize) {

        Long userId=45L;
        double maxDistance=5d;
        // 创建查询点
        Point point =  new Point( 120.90614024545896,31.977180294208473); // longitude, latitude
        // 第一步：查询符合条件的总数量
        Distance distance = new Distance(maxDistance, Metrics.KILOMETERS);
        Query query=new Query(Criteria.where("userId").ne(userId));

        // 1. 构建查询条件
        // 计算总数（通过不带分页的查询获取）
        NearQuery countQuery = NearQuery.near(point).maxDistance(distance).spherical(true).query(query);
        long total = mongoTemplate.geoNear(countQuery, MongoUserTrajectoryEntity.class).getContent().size();


        Pageable pageable = PageRequest.of(pageNum-1, pageSize);
        // 创建NearQuery，设置最大距离为5公里
        NearQuery nearQuery = NearQuery.near(point).maxDistance(distance).spherical(true).query(query).skip(pageable.getOffset()).limit(pageable.getPageSize());

        // 执行查询并返回分页结果
        List<MongoUserTrajectoryEntity> entities= mongoTemplate.geoNear(nearQuery, MongoUserTrajectoryEntity.class).getContent().stream()
                .map(geoResult -> {
                    MongoUserTrajectoryEntity entity = geoResult.getContent();
                    // 将计算的距离设置到实体中
                    entity.setRange(geoResult.getDistance());
                    return entity;
                })
                .collect(Collectors.toList());
        return new PageImpl<>(entities, pageable, total);
    }



}



